var utils = {
	fixNumber: function(num) {
		return num > 9 ? num : '0' + num;
	},
	getDateStr: function() {
		var date = new Date();
		return date.getFullYear().toString()
			+ utils.fixNumber(date.getMonth() + 1)
			+ utils.fixNumber(date.getDate())
			+ utils.fixNumber(date.getHours())
			+ utils.fixNumber(date.getMinutes());
	},
	isOverSizeFile: function(doc, sizeByte) {
		if (sizeByte === 'noLimit') return false;
		return File(doc.toString()).length > sizeByte;
	},
	getResizeBound: function(doc, rate) {
		var width = doc.width;
		var height = doc.height;

		var needWidth = height * rate, needHeight = height;
		if (width < needWidth) {
			needWidth = width;
			needHeight = width / rate;
		}

		var halfNeedWidth = needWidth / 2;
		var halfNeedHeight = needHeight / 2;
	
		var left = width > needWidth ? (width / 2 - halfNeedWidth) : 0;
		var top = height > needHeight ? (height / 2 - halfNeedHeight) : 0;
	
		return [left, top, width > needWidth ? (left + needWidth) : width, height > needHeight ? (top + needHeight) : height]
	},
	resizeSqare: function(size) {
		if (!size || size === 'auto') return;
		var doc = app.activeDocument, rate = 1;
		if (size !== '1:1') {
			var sizeConf = size.split('x');
			var needWidth = Number(sizeConf[0]);
			var needHeight = Number(sizeConf[1]);
			rate = needWidth / needHeight;
			doc.crop(utils.getResizeBound(doc, rate));
			doc.resizeImage(needWidth, needHeight, 72);
		} else {
			doc.crop(utils.getResizeBound(doc, rate));
		}
	},
	zipFile: function(quality, sizeByte) {
		var doc = app.activeDocument;
		if (utils.isOverSizeFile(doc.fullName, sizeByte)) {
			var saveOptions = new JPEGSaveOptions();
			saveOptions.quality = quality
			var newFile = File(doc.fullName)
			doc.saveAs(newFile, saveOptions, false);

			if (utils.isOverSizeFile(newFile, sizeByte) && quality > 1) {
				utils.zipFile(quality - 1, sizeByte)
			}
		}
	},
	getNewFilePath: function(baseFolderName, fileName, extendName) {
		var currentFile;
		while((currentFile = File(baseFolderName +'/' + fileName + extendName)).length > 0) {
			fileName += '_1';
		}
		return currentFile;
	},
	saveNewFile: function(fileDoc, baseFolderName, fileName, extendName, needReplace) {
		open(fileDoc);
		var doc = app.activeDocument;

		var folder = Folder(baseFolderName);
		if (!folder.exists) {
			folder.create();
		}

		var newDoc = needReplace
			? File(baseFolderName +'/' + fileName + extendName)
			: utils.getNewFilePath(baseFolderName, fileName, extendName);
		var saveOptions = new JPEGSaveOptions();
		saveOptions.quality = 12;
		var res = doc.saveAs(newDoc, saveOptions, true);

		doc.close(SaveOptions.DONOTSAVECHANGES);
		return newDoc;
	}
}

function TransClass(from, dist, filterRegexp, sizeByte, pixLimit, needReplace, fileNameSuffix) {
	this.from = from;
	this.dist = dist;
	this.filterRegexp = filterRegexp && new RegExp(filterRegexp);
	this.sizeByte = sizeByte;
	this.pixLimit = pixLimit;
	this.needReplace = needReplace;
	this.fileNameSuffix = fileNameSuffix || '';

	this.zip = function() {
		this.resolveFolder(this.from,  this.dist.toString() + '/');
	}
	this.resolveFile = function(fileDoc, baseFolderName, fileName, extendName) {
		app.open(utils.saveNewFile(fileDoc, baseFolderName, fileName, extendName, this.needReplace));
		utils.resizeSqare(this.pixLimit);
		utils.zipFile(11, this.sizeByte);
		app.activeDocument.close(SaveOptions.SAVECHANGES);
	},
	this.resolveFolder = function(folderObj, baseName) {
		var folderList = folderObj.getFiles();
		var fileIndex = 1;
		for (var i = 0; i < folderList.length; i++) {
			var folderItem = folderList[i];
			var folderName = folderItem.name;
			if (folderItem instanceof File) {
				var extendName = folderName.substr(-4);
				if (extendName && extendName.toLowerCase() === '.jpg' && (this.filterRegexp && this.filterRegexp.test(folderName.slice(0, -4)) || !this.filterRegexp)) {
					const signPrefixPos = folderName.indexOf('-');
					this.resolveFile(
						folderItem,
						baseName,
						(signPrefixPos > 0 ? folderName.substr(0, signPrefixPos + 1) : '') + (fileIndex ++) + this.fileNameSuffix,
						extendName.toLowerCase()
					);
				}
			} else {
				this.resolveFolder(folderItem, baseName + folderName + '/');
			}
		}
	}
}

var dialog=new Window (
	"dialog {\
		text: 'Setting',\
		size: [500, 300],\
		alignChildren: 'left',\
		fromPathSetting: Group {\
			from: StaticText{size:[60,16], text: 'From:'},\
			path: Button{size:[260,30],properties: {name: 'fromFolder'}, text:'Choose folder...'},\
		}\
		distPathSetting: Group {\
			dist: StaticText{size:[60,16],text: 'To:', paddings: 10},\
			path: Button{size:[260,30],properties: {name: 'toFolder'}, text:'Choose folder...'},\
		}\
		filterSetting: Group{\
			prefix: StaticText{size:[60,16], text: 'Filter Reg:'},\
			filter: EditText{size:[100,25], text: ''},\
		}\
		pixSetting: Group{\
			prefix: StaticText{size:[60,16], text: 'Pix Size:'},\
			pix: DropDownList{size:[80,25], helpTip: 'select one'},\
		}\
		sizeSetting: Group{\
			prefix: StaticText{size:[60,16], text: 'Size Limit:'},\
			limitSize: EditText{size:[100,25], text:'3000'},\
			limitType: DropDownList{size:[80,25], helpTip: 'select one'},\
		}\
		fileNameSetting: Group{\
			prefix: StaticText{size:[60,16], text: 'File suffix:'},\
			suffix: EditText{size:[100,25]},\
			needReplace: DropDownList{size:[80,25]},\
		}\
		footer: Button{text: 'start', alignment: 'left'},\
	}\
");

var fromFolder, distFolder;
dialog.sizeSetting.limitType.add('item', 'mb');
dialog.sizeSetting.limitType.add('item', 'kb');
dialog.sizeSetting.limitType.add('item', 'no limit');
dialog.sizeSetting.limitType.selection = 1;

dialog.pixSetting.pix.add('item', '1:1');
dialog.pixSetting.pix.add('item', '800x800');
dialog.pixSetting.pix.add('item', '800x1200');
dialog.pixSetting.pix.add('item', 'auto');
dialog.pixSetting.pix.selection = 0;

dialog.fileNameSetting.needReplace.add('item', 'save all');
dialog.fileNameSetting.needReplace.add('item', 'replace');
dialog.fileNameSetting.needReplace.selection = 0;
dialog.fileNameSetting.suffix.text = '_' + utils.getDateStr();

dialog.fromPathSetting.path.onClick = function() {
	fromFolder = Folder.selectDialog ("please select from folder");
	dialog.fromPathSetting.path.text = decodeURI(fromFolder.toString());
}
dialog.distPathSetting.path.onClick = function() {
	distFolder = Folder.selectDialog ("please select dist folder");
	dialog.distPathSetting.path.text = decodeURI(distFolder.toString());
}

dialog.footer.onClick = function() {
	if (!fromFolder || !distFolder) {
		alert('fromFolder & distFolder can not be empty');
		return;
	}
	dialog.footer.visible = false

	var limitTypeSelection = dialog.sizeSetting.limitType.selection;
	var limitType = limitTypeSelection && limitTypeSelection.toString();
	var pixLimit = dialog.pixSetting.pix.selection;
	var needReplace = dialog.fileNameSetting.needReplace.selection.toString() === 'replace';

	var limitSize = dialog.sizeSetting.limitSize.text;
	var filterRegexp = dialog.filterSetting.filter.text;
	var fileNameSuffix = dialog.fileNameSetting.suffix.text;

	dialog.close()
	new TransClass(
		fromFolder,
		distFolder,
		filterRegexp,
		limitType === 'no limit' ? 'noLimit' : (limitType === 'kb' ? limitSize * 1024 : limitSize * 1048576),
		pixLimit && pixLimit.toString(),
		needReplace,
		fileNameSuffix
	).zip();
}
dialog.show()